package com.tools.common.thread;

import com.tools.common.object.Note;

import java.util.Locale;
import java.util.concurrent.TimeUnit;

/**
 * 时间单位枚举
 * */
@Note("时间单位枚举")
public enum Timeunit {

    NANO(0, "nano", "纳秒", "ns"),
    MICRO(1, "micro", "微秒", "us"),
    MILL(2, "mill", "毫秒", "ms"),
    SECOND(3, "second", "秒", "s"),
    MINI(4, "mini", "分钟", "m"),
    HOUR(5, "hour", "小时", "h"),
    DAY(6, "day", "天", "d"),
    WEEK(7,"week", "周", "w"),
    MONTH_28(8, "month-28", "平年月", "LM"),
    MONTH_29(9, "month-29", "闰年月", "MM"),
    MONTH_30(10, "month-30", "小月", "M"),
    MONTH_31(11, "month-31", "大月", "BM"),
    YEAR_365(365, "year-365", "平年", "Y"),
    YEAR_366(366, "year-366", "闰年", "BY");

    @Note("代号")
    private final int code;

    @Note("名称简写")
    private final String value;

    @Note("中文解释")
    private final String text;

    @Note("英文简写单位")
    private final String unit;


    Timeunit(int code, String value, String text, String unit) {
        this.code = code;
        this.value = value;
        this.text = text;
        this.unit = unit;
    }

    public int getCode() {
        return this.code;
    }

    public String getValue() {
        return this.value;
    }

    public String getText() {
        return this.text;
    }

    public String getText(String newText) {
        return newText;
    }

    public String getUnit() {
        return unit;
    }

    public boolean eqValue(String value) {
        return this.value.equals(value);
    }

    public boolean eqIgnoreCaseValue(String value) {
        return this.value.equalsIgnoreCase(value);
    }

    public boolean eqText(String text) {
        return this.value.equals(text);
    }

    public boolean eqIgnoreCaseText(String text) {
        return this.value.equalsIgnoreCase(text);
    }

    public boolean eqUnit(String unit) {
        return this.unit.equals(unit);
    }

    public boolean eqIgnoreCaseUnit(String unit) {
        return this.unit.equalsIgnoreCase(unit);
    }


    @Override
    public String toString() {
        return unit;
    }

    @Note("根据枚举返回对应 【目标时间 + 对应英文简写单位】 的字符串")
    public String getHasUnitTime(long time) {
        switch (this) {
            case NANO: return time + NANO.unit;
            case MICRO: return time + MICRO.unit;
            case MILL: return time + MILL.unit;
            case SECOND: return time + SECOND.unit;
            case MINI: return time + MINI.unit;
            case HOUR: return time + HOUR.unit;
            case DAY: return time + DAY.unit;
            default: throw new IllegalArgumentException("简写的时间单位只能从【纳秒】精确到【天】");
        }
    }

    /* *******************************************************************************************
     *
     *           其他方法
     *
     * *******************************************************************************************
     * */


    @Note("安全地将当前枚举所对的时间单位转为 java.util.concurrent 包的时间单位。该转换过程是安全的，不抛异常")
    public TimeUnit asTimeUnitSafe() {
        switch (this) {
            case NANO: return TimeUnit.NANOSECONDS;
            case MICRO: return TimeUnit.MICROSECONDS;
            case MILL: return TimeUnit.MILLISECONDS;
            case SECOND: return TimeUnit.SECONDS;
            case MINI: return TimeUnit.MINUTES;
            case HOUR: return TimeUnit.HOURS;
            case DAY: return TimeUnit.DAYS;
            default: return null;
        }
    }


    @Note("将当前枚举所对的时间单位转为 java.util.concurrent 包的时间单位。如果没有对应的实例则抛出异常")
    public TimeUnit asTimeUnit() {
        TimeUnit timeUnit = asTimeUnitSafe();
        if(timeUnit == null) throw new ClassCastException("转换为 java.util.concurrent.TimeUnit 失败，不知 【" + this + "】 该怎么转");
        return timeUnit;
    }


    @Note("安全地将当前枚举所对的时间单位转为 java.util.concurrent 包的时间单位。该转换过程是安全的，不抛异常")
    public static TimeUnit asTimeUnitSafe(Timeunit src) {
        if(src == null) return null;
        return src.asTimeUnitSafe();
    }

    @Note("将当前枚举所对的时间单位转为 java.util.concurrent 包的时间单位")
    public static TimeUnit asTimeUnit(Timeunit src) {
        if(src == null) throw new NullPointerException("不知道 null 对应什么枚举实例");
        return src.asTimeUnit();
    }



    @Note("安全地根据入参的 code 代码获取枚举实例，获取不到不会抛异常")
    public static Timeunit getEnumSafe(int code) {
        switch (code) {
            case 0: return NANO;
            case 1: return MICRO;
            case 2: return MILL;
            case 3: return SECOND;
            case 4: return MINI;
            case 5: return HOUR;
            case 6: return DAY;
            case 7: return WEEK;
            case 8: return MONTH_28;
            case 9: return MONTH_29;
            case 10: return MONTH_30;
            case 11: return MONTH_31;
            case 365: return YEAR_365;
            case 366: return YEAR_366;
            default: return null;
        }
    }


    @Note("根据入参的 code 代码获取枚举实例，获取不到会抛异常")
    public static Timeunit getEnum(int code) {
        Timeunit timeunit = getEnumSafe(code);
        if(timeunit == null) {
            throw new IllegalArgumentException("不知道 【" + code + "】 是什么时间单位枚举的代码");
        }
        return timeunit;
    }


    @Note("安全地根据入参的 value 属性获取枚举实例，获取不到不会抛异常")
    public static Timeunit getEnumSafe(String value) {
        if(value == null) return null;
        switch (value.toLowerCase(Locale.ROOT)) {
            case "nano": return NANO;
            case "micro": return MICRO;
            case "mill": return MILL;
            case "second": return SECOND;
            case "mini": return MINI;
            case "hour": return HOUR;
            case "day": return DAY;
            case "week": return WEEK;
            case "month-28": return MONTH_28;
            case "month-29": return MONTH_29;
            case "month-30": return MONTH_30;
            case "month-31": return MONTH_31;
            case "year-365": return YEAR_365;
            case "year-366": return YEAR_366;
            default: return null;
        }
    }

    @Note("根据入参的 value 属性获取枚举实例，获取不到会抛异常")
    public static Timeunit getEnum(String value) {
        Timeunit timeunit = getEnumSafe(value);
        if(timeunit == null) {
            throw new IllegalArgumentException("不知道 【" + value + "】 是什么时间单位枚举的名称");
        }
        return timeunit;
    }


    @Note("安全地将 Java 原生时间枚举转为自定义的时间枚举，如果没有对应的实例则返回 null，不会抛异常")
    public static Timeunit getEnumSafe(TimeUnit timeUnit) {
        if(timeUnit == null) return null;
        switch (timeUnit) {
            case NANOSECONDS: return NANO;
            case MICROSECONDS: return MICRO;
            case MILLISECONDS: return MILL;
            case SECONDS: return SECOND;
            case MINUTES: return MINI;
            case HOURS: return HOUR;
            case DAYS: return DAY;
            default: return null;
        }
    }

    @Note("将 Java 原生时间枚举转为自定义的时间枚举，如果没有对应的实例则会抛异常")
    public static Timeunit getEnum(TimeUnit timeUnit) {
        Timeunit timeunit = getEnumSafe(timeUnit);
        if(timeunit == null) throw new ClassCastException("转换为 com.tools.common.thread.Timeunit 失败，不知 【" + timeUnit + "】 该怎么转");
        return timeunit;
    }


    @Note("安全地根据入参的 unit 单位属性获取枚举实例，获取不到不会抛异常")
    public static Timeunit getEnumSafeByUnit(String unit) {
        if(unit == null) return null;
        switch (unit) {
            case "ns": return NANO;
            case "us": return MICRO;
            case "ms": return MILL;
            case "s": return SECOND;
            case "m": return MINI;
            case "h": return HOUR;
            case "d": return DAY;
            case "w": return WEEK;
            case "LM": return MONTH_28;
            case "MM": return MONTH_29;
            case "M": return MONTH_30;
            case "BM": return MONTH_31;
            case "Y": return YEAR_365;
            case "BY": return YEAR_366;
            default: return null;
        }
    }


    @Note("根据入参的 unit 属性获取枚举实例，获取不到会抛异常")
    public static Timeunit getEnumByUnit(String unit) {
        Timeunit timeunit = getEnumSafeByUnit(unit);
        if(timeunit == null) {
            throw new IllegalArgumentException("不知道 【" + unit + "】 是什么时间单位");
        }
        return timeunit;
    }


    /* *******************************************************************************************
     *
     *           转换操作
     *
     * *******************************************************************************************
     * */

    @Note("将 sourceTime + sourceUnit（单位） 的时间转为当前 this 枚举所对应的时间数值返回。" +
            "如 sourceTime 为 【3】，sourceUnit 为分钟，this 为 SECOND（秒）" +
            "则返回值为 180")
    public long cast(long sourceTime, Timeunit sourceUnit) {
        switch (this) {
            case NANO: return toNano(sourceTime, sourceUnit);
            case MICRO: return toMicro(sourceTime, sourceUnit);
            case MILL: return toMill(sourceTime, sourceUnit);
            case SECOND: return toSecond(sourceTime, sourceUnit);
            case MINI: return toMini(sourceTime, sourceUnit);
            case HOUR: return toHour(sourceTime, sourceUnit);
            case DAY: return toDay(sourceTime, sourceUnit);
            case WEEK: return toWeek(sourceTime, sourceUnit);
            case MONTH_28: return to28DayMonth(sourceTime, sourceUnit);
            case MONTH_29: return to29DayMonth(sourceTime, sourceUnit);
            case MONTH_30: return to30DayMonth(sourceTime, sourceUnit);
            case MONTH_31: return to31DayMonth(sourceTime, sourceUnit);
            case YEAR_365: return to365DayYear(sourceTime, sourceUnit);
            case YEAR_366: return to366DayYear(sourceTime, sourceUnit);
            default: throw new IllegalArgumentException("不知道 " + this + " 枚举实例");
        }
    }

    public long cast(TimePair timePair) {
        return cast(timePair.getSourceTime(), timePair.getSourceTimeunit());
    }


    @Note("将 sourceTime + sourceUnit（单位） 的时间转为微秒值输出")
    public static long toNano(long sourceTime, Timeunit sourceUnit) {
        if(sourceTime <= 0) return sourceTime;
        switch (sourceUnit) {
            case NANO: return sourceTime;
            case MICRO: return sourceTime * 1000;
            case MILL: return sourceTime * 1000 * 1000;
            case SECOND: return sourceTime * 1000 * 1000 * 1000;
            case MINI: return sourceTime * 1000 * 1000 * 1000 * 60;
            case HOUR: return sourceTime * 1000 * 1000 * 1000 * 60 * 60;
            case DAY: return sourceTime * 1000 * 1000 * 1000 * 60 * 60 * 24;
            case WEEK: return sourceTime * 1000 * 1000 * 1000 * 60 * 60 * 24 * 7;
            case MONTH_28: return sourceTime * 1000 * 1000 * 1000 * 60 * 60 * 24 * 28;
            case MONTH_29: return sourceTime * 1000 * 1000 * 1000 * 60 * 60 * 24 * 29;
            case MONTH_30: return sourceTime * 1000 * 1000 * 1000 * 60 * 60 * 24 * 30;
            case MONTH_31: return sourceTime * 1000 * 1000 * 1000 * 60 * 60 * 24 * 31;
            case YEAR_365: return sourceTime * 1000 * 1000 * 1000 * 60 * 60 * 24 * 365;
            case YEAR_366: return sourceTime * 1000 * 1000 * 1000 * 60 * 60 * 24 * 366;
            default: throw new IllegalArgumentException("不知道 " + sourceUnit + " 枚举实例");
        }
    }

    public static long toNano(TimePair timePair) {
        return toNano(timePair.getSourceTime(), timePair.getSourceTimeunit());
    }

    @Note("将 sourceTime + sourceUnit（单位） 的时间转为微秒值输出")
    public static long toMicro(long sourceTime, Timeunit sourceUnit) {
        if(sourceTime <= 0) return sourceTime;
        switch (sourceUnit) {
            case NANO: return sourceTime / 1000;
            case MICRO: return sourceTime;
            case MILL: return sourceTime * 1000;
            case SECOND: return sourceTime * 1000 * 1000;
            case MINI: return sourceTime * 1000 * 1000 * 60;
            case HOUR: return sourceTime * 1000 * 1000 * 60 * 60;
            case DAY: return sourceTime * 1000 * 1000 * 60 * 60 * 24;
            case WEEK: return sourceTime * 1000 * 1000 * 60 * 60 * 24 * 7;
            case MONTH_28: return sourceTime * 1000 * 1000 * 60 * 60 * 24 * 28;
            case MONTH_29: return sourceTime * 1000 * 1000 * 60 * 60 * 24 * 29;
            case MONTH_30: return sourceTime * 1000 * 1000 * 60 * 60 * 24 * 30;
            case MONTH_31: return sourceTime * 1000 * 1000 * 60 * 60 * 24 * 31;
            case YEAR_365: return sourceTime * 1000 * 1000 * 60 * 60 * 24 * 365;
            case YEAR_366: return sourceTime * 1000 * 1000 * 60 * 60 * 24 * 366;
            default: throw new IllegalArgumentException("不知道 " + sourceUnit + " 枚举实例");
        }
    }

    public static long toMicro(TimePair timePair) {
        return toMicro(timePair.getSourceTime(), timePair.getSourceTimeunit());
    }


    @Note("将 sourceTime + sourceUnit（单位） 的时间转为毫秒值输出")
    public static long toMill(long sourceTime, Timeunit sourceUnit) {
        if(sourceTime <= 0) return sourceTime;
        switch (sourceUnit) {
            case NANO: return sourceTime / 1000 / 1000;
            case MICRO: return sourceTime / 1000;
            case MILL: return sourceTime;
            case SECOND: return sourceTime * 1000;
            case MINI: return sourceTime * 1000 * 60;
            case HOUR: return sourceTime * 1000 * 60 * 60;
            case DAY: return sourceTime * 1000 * 60 * 60 * 24;
            case WEEK: return sourceTime * 1000 * 60 * 60 * 24 * 7;
            case MONTH_28: return sourceTime * 1000 * 60 * 60 * 24 * 28;
            case MONTH_29: return sourceTime * 1000 * 60 * 60 * 24 * 29;
            case MONTH_30: return sourceTime * 1000 * 60 * 60 * 24 * 30;
            case MONTH_31: return sourceTime * 1000 * 60 * 60 * 24 * 31;
            case YEAR_365: return sourceTime * 1000 * 60 * 60 * 24 * 365;
            case YEAR_366: return sourceTime * 1000 * 60 * 60 * 24 * 366;
            default: throw new IllegalArgumentException("不知道 " + sourceUnit + " 枚举实例");
        }
    }


    public static long toMill(TimePair timePair) {
        return toMill(timePair.getSourceTime(), timePair.getSourceTimeunit());
    }

    @Note("将 sourceTime + sourceUnit（单位） 的时间转为秒值输出")
    public static long toSecond(long sourceTime, Timeunit sourceUnit) {
        if(sourceTime <= 0) return sourceTime;
        switch (sourceUnit) {
            case NANO: return sourceTime / 1000 / 1000 / 1000;
            case MICRO: return sourceTime / 1000 / 1000;
            case MILL: return sourceTime / 1000;
            case SECOND: return sourceTime;
            case MINI: return sourceTime * 60;
            case HOUR: return sourceTime * 60 * 60;
            case DAY: return sourceTime * 60 * 60 * 24;
            case WEEK: return sourceTime * 60 * 60 * 24 * 7;
            case MONTH_28: return sourceTime * 60 * 60 * 24 * 28;
            case MONTH_29: return sourceTime * 60 * 60 * 24 * 29;
            case MONTH_30: return sourceTime * 60 * 60 * 24 * 30;
            case MONTH_31: return sourceTime * 60 * 60 * 24 * 31;
            case YEAR_365: return sourceTime * 60 * 60 * 24 * 365;
            case YEAR_366: return sourceTime * 60 * 60 * 24 * 366;
            default: throw new IllegalArgumentException("不知道 " + sourceUnit + " 枚举实例");
        }
    }

    public static long toSecond(TimePair timePair) {
        return toSecond(timePair.getSourceTime(), timePair.getSourceTimeunit());
    }

    @Note("将 sourceTime + sourceUnit（单位） 的时间转为分钟值输出")
    public static long toMini(long sourceTime, Timeunit sourceUnit) {
        if(sourceTime <= 0) return sourceTime;
        switch (sourceUnit) {
            case NANO: return sourceTime / 60 / 1000 / 1000 / 1000;
            case MICRO: return sourceTime / 60 / 1000 / 1000;
            case MILL: return sourceTime / 60 / 1000;
            case SECOND: return sourceTime / 60;
            case MINI: return sourceTime;
            case HOUR: return sourceTime * 60;
            case DAY: return sourceTime * 60 * 24;
            case WEEK: return sourceTime * 60 * 24 * 7;
            case MONTH_28: return sourceTime * 60 * 24 * 28;
            case MONTH_29: return sourceTime * 60 * 24 * 29;
            case MONTH_30: return sourceTime * 60 * 24 * 30;
            case MONTH_31: return sourceTime * 60 * 24 * 31;
            case YEAR_365: return sourceTime * 60 * 24 * 365;
            case YEAR_366: return sourceTime * 60 * 24 * 366;
            default: throw new IllegalArgumentException("不知道 " + sourceUnit + " 枚举实例");
        }
    }

    public static long toMini(TimePair timePair) {
        return toMini(timePair.getSourceTime(), timePair.getSourceTimeunit());
    }

    @Note("将 sourceTime + sourceUnit（单位） 的时间转为小时值输出")
    public static long toHour(long sourceTime, Timeunit sourceUnit) {
        if(sourceTime <= 0) return sourceTime;
        switch (sourceUnit) {
            case NANO: return sourceTime / 60 / 60 / 1000 / 1000 / 1000;
            case MICRO: return sourceTime / 60 / 60 / 1000 / 1000;
            case MILL: return sourceTime / 60 / 60 / 1000;
            case SECOND: return sourceTime / 60 / 60;
            case MINI: return sourceTime / 60;
            case HOUR: return sourceTime;
            case DAY: return sourceTime * 24;
            case WEEK: return sourceTime * 24 * 7;
            case MONTH_28: return sourceTime * 24 * 28;
            case MONTH_29: return sourceTime * 24 * 29;
            case MONTH_30: return sourceTime * 24 * 30;
            case MONTH_31: return sourceTime * 24 * 31;
            case YEAR_365: return sourceTime * 24 * 365;
            case YEAR_366: return sourceTime * 24 * 366;
            default: throw new IllegalArgumentException("不知道 " + sourceUnit + " 枚举实例");
        }
    }

    public static long toHour(TimePair timePair) {
        return toHour(timePair.getSourceTime(), timePair.getSourceTimeunit());
    }


    @Note("将 sourceTime + sourceUnit（单位） 的时间转为天值输出")
    public static long toDay(long sourceTime, Timeunit sourceUnit) {
        if(sourceTime <= 0) return sourceTime;
        switch (sourceUnit) {
            case NANO: return sourceTime / 24 / 60 / 60 / 1000 / 1000 / 1000;
            case MICRO: return sourceTime / 24 / 60 / 60 / 1000 / 1000;
            case MILL: return sourceTime / 24 / 60 / 60 / 1000;
            case SECOND: return sourceTime / 24 / 60 / 60;
            case MINI: return sourceTime / 24 / 60;
            case HOUR: return sourceTime / 24;
            case DAY: return sourceTime;
            case WEEK: return sourceTime * 7;
            case MONTH_28: return sourceTime * 28;
            case MONTH_29: return sourceTime * 29;
            case MONTH_30: return sourceTime * 30;
            case MONTH_31: return sourceTime * 31;
            case YEAR_365: return sourceTime * 365;
            case YEAR_366: return sourceTime * 366;
            default: throw new IllegalArgumentException("不知道 " + sourceUnit + " 枚举实例");
        }
    }

    public static long toDay(TimePair timePair) {
        return toDay(timePair.getSourceTime(), timePair.getSourceTimeunit());
    }

    @Note("将 sourceTime + sourceUnit（单位） 的时间转为周值输出")
    public static long toWeek(long sourceTime, Timeunit sourceUnit) {
        if(sourceTime <= 0) return sourceTime;
        switch (sourceUnit) {
            case NANO: return sourceTime / 7 / 24 / 60 / 60 / 1000 / 1000 / 1000;
            case MICRO: return sourceTime / 7 / 24 / 60 / 60 / 1000 / 1000;
            case MILL: return sourceTime / 7 / 24 / 60 / 60 / 1000;
            case SECOND: return sourceTime / 7 / 24 / 60 / 60;
            case MINI: return sourceTime / 7 / 24 / 60;
            case HOUR: return sourceTime / 7 / 24;
            case DAY: return sourceTime / 7;
            case WEEK: return sourceTime;
            case MONTH_28: return sourceTime * 28 / 7;
            case MONTH_29: return sourceTime * 29 / 7;
            case MONTH_30: return sourceTime * 30 / 7;
            case MONTH_31: return sourceTime * 31 / 7;
            case YEAR_365: return sourceTime * 365 / 7;
            case YEAR_366: return sourceTime * 366 / 7;
            default: throw new IllegalArgumentException("不知道 " + sourceUnit + " 枚举实例");
        }
    }

    public static long toWeek(TimePair timePair) {
        return toWeek(timePair.getSourceTime(), timePair.getSourceTimeunit());
    }

    @Note("将 sourceTime + sourceUnit（单位） 的时间转为 28 天的月份值输出")
    public static long to28DayMonth(long sourceTime, Timeunit sourceUnit) {
        if(sourceTime <= 0) return sourceTime;
        switch (sourceUnit) {
            case NANO: return sourceTime / 28 / 24 / 60 / 60 / 1000 / 1000 / 1000;
            case MICRO: return sourceTime / 28 / 24 / 60 / 60 / 1000 / 1000;
            case MILL: return sourceTime / 28 / 24 / 60 / 60 / 1000;
            case SECOND: return sourceTime / 28 / 24 / 60 / 60;
            case MINI: return sourceTime / 28 / 24 / 60;
            case HOUR: return sourceTime / 28 / 24;
            case DAY: return sourceTime / 28;
            case WEEK: return sourceTime / 28 * 7;
            case MONTH_28: return sourceTime;
            case MONTH_29: return sourceTime * 29 / 28;
            case MONTH_30: return sourceTime * 30 / 28;
            case MONTH_31: return sourceTime * 31 / 28;
            case YEAR_365: return sourceTime * 365 / 28;
            case YEAR_366: return sourceTime * 366 / 28;
            default: throw new IllegalArgumentException("不知道 " + sourceUnit + " 枚举实例");
        }
    }

    public static long to28DayMonth(TimePair timePair) {
        return to28DayMonth(timePair.getSourceTime(), timePair.getSourceTimeunit());
    }

    @Note("将 sourceTime + sourceUnit（单位） 的时间转为 29 天的月份值输出")
    public static long to29DayMonth(long sourceTime, Timeunit sourceUnit) {
        if(sourceTime <= 0) return sourceTime;
        switch (sourceUnit) {
            case NANO: return sourceTime / 29 / 24 / 60 / 1000 / 1000 / 1000;
            case MICRO: return sourceTime / 29 / 24 / 60 / 1000 / 1000;
            case MILL: return sourceTime / 29 / 24 / 60 / 1000;
            case SECOND: return sourceTime / 29 / 24 / 60 / 60;
            case MINI: return sourceTime / 29 / 24 / 60;
            case HOUR: return sourceTime / 29 / 24;
            case DAY: return sourceTime / 29;
            case WEEK: return sourceTime / 29 * 7;
            case MONTH_28: return sourceTime / 29 * 28;
            case MONTH_29: return sourceTime;
            case MONTH_30: return sourceTime * 30 / 29;
            case MONTH_31: return sourceTime * 31 / 29;
            case YEAR_365: return sourceTime * 365 / 29;
            case YEAR_366: return sourceTime * 366 / 29;
            default: throw new IllegalArgumentException("不知道 " + sourceUnit + " 枚举实例");
        }
    }

    public static long to29DayMonth(TimePair timePair) {
        return to29DayMonth(timePair.getSourceTime(), timePair.getSourceTimeunit());
    }


    @Note("将 sourceTime + sourceUnit（单位） 的时间转为 30 天的月份值输出")
    public static long to30DayMonth(long sourceTime, Timeunit sourceUnit) {
        if(sourceTime <= 0) return sourceTime;
        switch (sourceUnit) {
            case NANO: return sourceTime / 30 / 24 / 60 / 60 / 1000 / 1000 / 1000;
            case MICRO: return sourceTime / 30 / 24 / 60 / 60 / 1000 / 1000;
            case MILL: return sourceTime / 30 / 24 / 60 / 60 / 1000;
            case SECOND: return sourceTime / 30 / 24 / 60 / 60;
            case MINI: return sourceTime / 30 / 24 / 60;
            case HOUR: return sourceTime / 30 / 24;
            case DAY: return sourceTime / 30;
            case WEEK: return sourceTime / 30 * 7;
            case MONTH_28: return sourceTime / 30 * 28;
            case MONTH_29: return sourceTime / 30 * 29;
            case MONTH_30: return sourceTime;
            case MONTH_31: return sourceTime * 31 / 30;
            case YEAR_365: return sourceTime * 365 / 30;
            case YEAR_366: return sourceTime * 366 / 30;
            default: throw new IllegalArgumentException("不知道 " + sourceUnit + " 枚举实例");
        }
    }

    public static long to30DayMonth(TimePair timePair) {
        return to30DayMonth(timePair.getSourceTime(), timePair.getSourceTimeunit());
    }

    @Note("将 sourceTime + sourceUnit（单位） 的时间转为 31 天的月份值输出")
    public static long to31DayMonth(long sourceTime, Timeunit sourceUnit) {
        if(sourceTime <= 0) return sourceTime;
        switch (sourceUnit) {
            case NANO: return sourceTime / 31 / 24 / 60 / 60 / 1000 / 1000 / 1000;
            case MICRO: return sourceTime / 31 / 24 / 60 / 60 / 1000 / 1000;
            case MILL: return sourceTime / 31 / 24 / 60 / 60 / 1000;
            case SECOND: return sourceTime / 31 / 24 / 60 / 60;
            case MINI: return sourceTime / 31 / 24 / 60;
            case HOUR: return sourceTime / 31 / 24;
            case DAY: return sourceTime / 31;
            case WEEK: return sourceTime / 31 * 7;
            case MONTH_28: return sourceTime / 31 * 28;
            case MONTH_29: return sourceTime / 31 * 29;
            case MONTH_30: return sourceTime / 31 * 30;
            case MONTH_31: return sourceTime;
            case YEAR_365: return sourceTime * 365 / 31;
            case YEAR_366: return sourceTime * 366 / 31;
            default: throw new IllegalArgumentException("不知道 " + sourceUnit + " 枚举实例");
        }
    }

    public static long to31DayMonth(TimePair timePair) {
        return to31DayMonth(timePair.getSourceTime(), timePair.getSourceTimeunit());
    }

    @Note("将 sourceTime + sourceUnit（单位） 的时间转为 365 天的年份值输出")
    public static long to365DayYear(long sourceTime, Timeunit sourceUnit) {
        if(sourceTime <= 0) return sourceTime;
        switch (sourceUnit) {
            case NANO: return sourceTime / 365 / 24 / 60 / 60 / 1000 / 1000 / 1000;
            case MICRO: return sourceTime / 365 / 24 / 60 / 60 / 1000 / 1000;
            case MILL: return sourceTime / 365 / 24 / 60 / 60 / 1000;
            case SECOND: return sourceTime / 365 / 24 / 60 / 60;
            case MINI: return sourceTime / 365 / 24 / 60;
            case HOUR: return sourceTime / 365 / 24;
            case DAY: return sourceTime / 365;
            case WEEK: return sourceTime / 365 * 7;
            case MONTH_28: return sourceTime / 365 * 28;
            case MONTH_29: return sourceTime / 365 * 29;
            case MONTH_30: return sourceTime / 365 * 30;
            case MONTH_31: return sourceTime / 365 * 31;
            case YEAR_365: return sourceTime;
            case YEAR_366: return sourceTime * 366 / 365;
            default: throw new IllegalArgumentException("不知道 " + sourceUnit + " 枚举实例");
        }
    }

    public static long to365DayYear(TimePair timePair) {
        return to365DayYear(timePair.getSourceTime(), timePair.getSourceTimeunit());
    }


    @Note("将 sourceTime + sourceUnit（单位） 的时间转为 366 天的年份值输出")
    public static long to366DayYear(long sourceTime, Timeunit sourceUnit) {
        if(sourceTime <= 0) return sourceTime;
        switch (sourceUnit) {
            case NANO: return sourceTime / 366 / 24 / 60 / 60 / 1000 / 1000 / 1000;
            case MICRO: return sourceTime / 366 / 24 / 60 / 60 / 1000 / 1000;
            case MILL: return sourceTime / 366 / 24 / 60 / 60 / 1000;
            case SECOND: return sourceTime / 366 / 24 / 60 / 60;
            case MINI: return sourceTime / 366 / 24 / 60;
            case HOUR: return sourceTime / 366 / 24;
            case DAY: return sourceTime / 366;
            case WEEK: return sourceTime / 366 * 7;
            case MONTH_28: return sourceTime / 366 * 28;
            case MONTH_29: return sourceTime / 366 * 29;
            case MONTH_30: return sourceTime / 366 * 30;
            case MONTH_31: return sourceTime / 366 * 31;
            case YEAR_365: return sourceTime / 366 * 365;
            case YEAR_366: return sourceTime;
            default: throw new IllegalArgumentException("不知道 " + sourceUnit + " 枚举实例");
        }
    }

    public static long to366DayYear(TimePair timePair) {
        return to366DayYear(timePair.getSourceTime(), timePair.getSourceTimeunit());
    }
}
